<script setup>
import 'vant/es/dialog/style'
import {getAddressAPI} from "@/api/address.js";
import {ADDRESS_LIST_ROUTE} from "@/router/routes/address/AddressList.js";
import useOrderStore from "@/store/modules/OrderStore.js";
import TailPrice from "@/components/TailPrice.vue";
import {getProductById} from "@/api/product.js";
import {updateCarProductAPI} from "@/api/car.js";
import {rsaPubEncrypt} from "@/utils/EncryptUtils.js";
import {addOrderAPI} from "@/api/order.js";
import {elErrorMessageTip, elSuccessMessageTip} from "@/utils/MessageTipUtils.js";
import {PAY_ROUTE} from "@/router/routes/order/pay.js";
import {ref, onBeforeMount, watchEffect} from 'vue'
import {useRouter, useRoute} from 'vue-router'
import 'vant/es/image-preview/style'
import {showConfirmDialog, showImagePreview} from "vant";

const router = useRouter()
const route = useRoute()

const goBack = () => {
  showConfirmDialog({
    message: '是否确认放弃本次的订单'
  }).then(() => {
    // on confirm
    router.back()
  }).catch(() => {
    // on cancel
  });
}

const addressList = ref([])
const addressListShow = ref([])
const addressSelect = ref({})
const addressSelectShow = ref({})
const chosenAddressId = ref('1');
const convert2addressShow = (addressSelect) => {
  return {
    id: addressSelect.id,
    name: addressSelect.name,
    tel: addressSelect.phone,
    isDefault: addressSelect.idDefault,
    address: addressSelect.province + addressSelect.city + addressSelect.county + addressSelect.address,
  }
}
const carList = ref([])
const allPrice = ref(0)
onBeforeMount(async () => {
  carList.value = useOrderStore().products
  addressList.value = await getAddressAPI()
  let defaultAddress = null;
  addressList.value = addressList.value.filter(item => {
    if (item.idDefault) {
      defaultAddress = item;
      return false;
    }
    return item.idDefault === false;
  })
  if (defaultAddress !== null) addressList.value.unshift(defaultAddress)
  if (addressList.value.length >= 1) {
    addressSelect.value = addressList.value[0]
    addressListShow.value = addressList.value.map(
        item => convert2addressShow(item)
    )
    addressSelectShow.value = convert2addressShow(addressSelect.value)
    chosenAddressId.value = addressSelectShow.value.id
  } else {
    addressSelectShow.value = {
      id: '',
      name: '还未添加收货地址',
      tel: '',
      isDefault: false,
      address: '点击前往添加收货地址'
    }
  }
})
const allFreight = ref(0)
watchEffect(() => {
  allPrice.value = 0.0
  allFreight.value = 0.0
  for (let i = 0; i < carList.value.length; i++) {
    allFreight.value += carList.value[i].freight
    allFreight.value = Math.round(allFreight.value * 100) / 100
    allPrice.value += carList.value[i].price * carList.value[i].num + carList.value[i].freight
    allPrice.value = Math.round(allPrice.value * 100) / 100
  }
})

const floatPanelVisibleAddr = ref(false)
const anchorsAddr = ref([window.innerHeight * 0.3, window.innerHeight * 0.5, window.innerHeight * 0.8])
const onOpenPanelAddr = async () => {
  floatPanelVisibleAddr.value = true
}
const onClosePanelAddr = () => {
  floatPanelVisibleAddr.value = false
}
const goAddressList = () => {
  router.push({name: ADDRESS_LIST_ROUTE})
}
const onAddressSelect = (item, idx) => {
  addressSelect.value = addressList.value[idx]
  addressSelectShow.value = item
  chosenAddressId.value = item.id
  onClosePanelAddr()
}

const floatPanelVisible = ref(false)
const anchors = ref([window.innerHeight * 0.85])
const product = ref({})
const carProductId = ref(0)
const productId = ref(0)
const carProductNum = ref(0)
const updateOptionProductIdx = ref(0)
// 当前选中的商品图片、商品选项名称、商品选项价格
const productImgSelected = ref('')
const productOptionNameSelected = ref('')
const productOptionPriceSelected = ref(0)
const productOptionIdx = ref(0)
const newProductOptionId = ref(0)
const onOpenPanel = async (carProductId_, productId_, productOptionId, carProductIdx) => {
  carProductId.value = carProductId_
  productId.value = productId_
  // carProductNum.value = carListNums.value[carProductIdx]
  updateOptionProductIdx.value = carProductIdx
  // 获取商品信息
  product.value = await getProductById(productId_)
  let idx = 0;
  for (let i = 0; i < product.value.options.length; i++) {
    if (product.value.options[i].id === productOptionId) {
      idx = i
      break
    }
  }
  productOptionIdx.value = idx
  productImgSelected.value = product.value?.options[idx].img
  productOptionNameSelected.value = product?.value.options[idx].name
  productOptionPriceSelected.value = product?.value.options[idx].price
  newProductOptionId.value = product?.value.options[idx].id
  floatPanelVisible.value = true
}
const onClosePanel = () => {
  floatPanelVisible.value = false
}
// 商品选项选择
const selectProductOption = (option, idx) => {
  if (option?.stock <= 0) return
  productImgSelected.value = option?.img
  productOptionNameSelected.value = option?.name
  productOptionPriceSelected.value = option?.price
  newProductOptionId.value = option?.id
  productOptionIdx.value = idx
};
// 商品选项图片预览
const productOptionImgPreview = () => {
  showImagePreview([productImgSelected.value]);
}
// 更新商品选项
const updateCarProductOption = async () => {
  carList.value[updateOptionProductIdx.value].img = productImgSelected.value
  carList.value[updateOptionProductIdx.value].name = productOptionNameSelected.value
  carList.value[updateOptionProductIdx.value].price = productOptionPriceSelected.value
  carList.value[updateOptionProductIdx.value].productOptionId = newProductOptionId.value
  carList.value[updateOptionProductIdx.value].stock = product.value.options[productOptionIdx.value].stock
  onClosePanel()
}

const onSubmitOrder = async () => {
  // 订单编号列表
  const orderIdList = []
  // 遍历所有订单进行提交
  for (let item of carList.value) {
    // 创建订单信息对象
    const orders = {
      id: null, // 编号
      carId: item.id, // 购物车书籍商品编号
      userId: item.userId, // 用户编号
      productId: item.productId, // 书籍商品编号
      productOptionId: item.productOptionId, // 书籍商品选项编号
      productOptionName: rsaPubEncrypt(item.name), // 书籍商品选项名称
      productOptionPrice: item.price, // 书籍商品选项价格
      productOptionImg: rsaPubEncrypt(item.img), // 书籍商品选项图片
      num: item.num, // 购买数量
      status: 1, // 订单状态
      name: rsaPubEncrypt(addressSelect.value.name), // 收货人姓名
      phone: rsaPubEncrypt(addressSelect.value.phone), // 收货人手机号
      province: rsaPubEncrypt(addressSelect.value.province), // 收货地省份
      freight: item.freight, // 运费
      city: rsaPubEncrypt(addressSelect.value.city), // 收货地城市
      county: rsaPubEncrypt(addressSelect.value.county), // 收货地区县
      address: rsaPubEncrypt(addressSelect.value.address) // 收货详细地址
    }
    // 提交订单结果
    const res = await addOrderAPI(orders)
    // 订单提交失败，进行错误信息提示
    if (!res.status) {
      elErrorMessageTip(res.msg)
      return
    }
    // 订单提交成功，保存订单编号
    orderIdList.push(res.data)
  }
  // 保存订单编号列表
  useOrderStore().saveOrderIdList(orderIdList)
  elSuccessMessageTip("订单提交成功")
  // 跳转到订单支付页面
  router.replace({name: PAY_ROUTE})
}
</script>

<template>
  <div class="orders">
    <van-nav-bar :title="'确认订单'" left-text="返回" left-arrow fixed @click-left="goBack" placeholder/>
    <van-address-list
        @click="onOpenPanelAddr"
        :list="[addressSelectShow]"
        :show-add-button="false"
        :switchable="false"
        default-tag-text="默认"
        right-icon="arrow"
    />
    <div class="pb-16">
      <div v-for="(item, idx) in carList">
        <div class="mb-2 ml-3 mr-3 p-1 pl-2 bg-white dark:bg-neutral-900 flex justify-start items-stretch">
          <div class="option-img w-1/6 mr-2 rounded-xl overflow-hidden"
          >
            <img class="w-full h-full object-contain" :src="item?.img" alt="">
          </div>
          <div class="pt-1 w-9/12">
            <div class="truncate dark:text-gray-100"
            >{{ item?.title }}
            </div>
            <div
                class="option-name mt-1 mb-1 p-0.5 pl-2 pr-2 rounded-md bg-gray-300 truncate text-gray-500 text-xs"
                @click.self.stop="onOpenPanel(item?.id, item?.productId, item?.productOptionId, idx)"
            >{{ item?.name }}
            </div>
            <div class="flex justify-between items-center">
              <TailPrice
                  :price="item?.price.toString()"
                  :is-start="false"
              ></TailPrice>
              <van-stepper
                  v-model="carList[idx].num"
                  integer
                  :min="1"
                  :max="item?.stock"
                  theme="round"
                  button-size="20"
              />
            </div>
          </div>
        </div>
      </div>
    </div>
    <div class="w-screen p-2 bg-white dark:bg-neutral-900 fixed bottom-0 left-0 flex justify-between items-center">
      <div class="mr-2 flex justify-start items-center">
        <span class="dark:text-gray-100">运费：</span>
        <TailPrice :price="allFreight.toString()" :is-start="false"></TailPrice>
        <span class="ml-2 dark:text-gray-100">合计：</span>
        <TailPrice :price="allPrice.toString()" :is-start="false"></TailPrice>
      </div>
      <van-button
          color="linear-gradient(to right, #ff6034, #ee0a24)"
          round
          @click="onSubmitOrder"
      >
        提交订单
      </van-button>
    </div>
    <van-overlay :show="floatPanelVisibleAddr" @click="onClosePanelAddr" lock-scroll></van-overlay>
    <van-floating-panel :anchors="anchorsAddr" v-show="floatPanelVisibleAddr">
      <van-address-list
          v-if="addressListShow.length > 0"
          v-model="chosenAddressId"
          :list="addressListShow"
          :show-add-button="false"
          :switchable="true"
          default-tag-text="默认"
          right-icon=""
          @select="onAddressSelect"
      />
      <div class="mt-2 p-2">
        <van-button block
                    round
                    @click="goAddressList"
                    color="linear-gradient(to right, #e26226, #f52d2a, #e26226)">
          前往编辑收货地址
        </van-button>
      </div>
    </van-floating-panel>
    <van-overlay :show="floatPanelVisible" @click="onClosePanel" lock-scroll>
      <div class="flex-start-center pl-4 pr-4 pt-4">
        <div class="img w-16 h-16 mr-2 flex-nowrap">
          <img class="w-full h-full object-contain"
               :src="productImgSelected" alt=""
               @click.stop="productOptionImgPreview"
          >
        </div>
        <div class="name text-sm text-gray-100 w-5/6">
          {{ productOptionNameSelected }}
        </div>
      </div>
    </van-overlay>
    <van-floating-panel
        :content-draggable="true"
        :anchors="anchors"
        v-show="floatPanelVisible"
    >
      <div class="h-full flex flex-col justify-between">
        <div class="p-2">
          <div class="flex justify-between items-center">
            <TailPrice
                :price="productOptionPriceSelected.toString()"
                :isStart="false"
            ></TailPrice>
            <div class="mr-4 text-neutral-600 dark:text-gray-200" @click="onClosePanel">
              <span class="iconfont icon-close"></span>
            </div>
          </div>
          <div
              v-for="(item, idx) in product?.options"
              @click="selectProductOption(item, idx)"
              class="product-option bg-gray-50 dark:bg-neutral-950 dark:text-gray-100 mt-2 p-2 rounded-xl overflow-hidden flex justify-between items-center"
              :class="[productOptionIdx === idx ? 'product-option-selected' : '', item?.stock <= 0 ? 'text-gray-300' : '']"
          >
            <div class="flex-start-center">
              <div class="img w-12 h-12 mr-2">
                <img class="w-full h-full object-contain" :src="item.img" alt="">
              </div>
              <div class="name text-sm w-52">
                {{ item?.name }}
              </div>
            </div>
            <div class="price text-sm flex-nowrap">￥ {{ item?.price }}</div>
          </div>
        </div>
        <div class="p-4">
          <van-button color="linear-gradient(to right, #ff8a17, #ee0a24)"
                      @click="updateCarProductOption"
                      round block
          >
            确定
          </van-button>
        </div>
      </div>
    </van-floating-panel>
  </div>
</template>

<style lang="scss">
.orders {
  --van-address-list-padding: 10px;
}

.product-option {
  border: 1px solid transparent;
  font-weight: 300;
}

.product-option-selected {
  border: 1px solid #ff5000;
}

.option-img {
  min-width: 4.5rem;
  max-width: 6rem;
}

.option-name {
  width: min-content;
  max-width: 70%;
}
</style>